package com.googlecode.curvedmetromaps.core.logic.costfunction;

import com.googlecode.curvedmetromaps.core.model.MetroMap;
import com.googlecode.curvedmetromaps.core.model.MetroStation;

/**
 * Cost function that keeps vertices apart.
 */
public class VertexVertexDistanceCost extends BaseCost {

	public VertexVertexDistanceCost(MetroMap map) {
		super(map);

		createWeight("base", "Base weight", 0.1);
		
		// Distance lower than this value will be rounded up. 
		createWeight("mindist", "Minimum distance", 0.0001);
	}

	@Override
	public String getName() {
		return "Vertix-vertex distance";
	}

	@Override
	public double calculateCost() {
		double result = 0;
		double minDistSq = Math.pow(getWeight("mindist"), 2);
		int count = 0;

		for (MetroStation m1 : map.stations) {
			for (MetroStation m2 : map.stations) {
				if (m1.id < m2.id) {
					float dx = m1.x - m2.x;
					float dy = m1.y - m2.y;
					double distSq = dx * dx + dy * dy;
					// Cost for (u,v) and (v,u)
					if (distSq < minDistSq) distSq = minDistSq;
					double cost = 2 / distSq;
					result += cost;
					count++;
				}
			}
		}

		// Calculate average cost per vertex pair
		result /= count;

		return getWeight("base") * result;
	}

}
